<!DOCTYPE html>
<html>

<head>
    <title>dispose test</title>
    <script type="text/javascript" src="https://unpkg.com/randomcolor@0.6.2/randomColor.js"></script>
    <script type="text/javascript" src="https://unpkg.com/dat.gui@0.7.6/build/dat.gui.min.js"></script>
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/maptalks/dist/maptalks.css">
    <script type="text/javascript" src="https://unpkg.com/maptalks/dist/maptalks.js"></script>
    <script type="text/javascript" src="https://unpkg.com/@maptalks/gl/dist/maptalksgl.js"></script>
    <script type="text/javascript" src="https://unpkg.com/three@0.138.0/build/three.min.js"></script>
    <script type="text/javascript"
        src="https://unpkg.com/maptalks.three@latest/dist/maptalks.three.js"></script>
    <script type="text/javascript"
        src="https://unpkg.com/three@0.138.0/examples/js/libs/stats.min.js"></script>
    <style>
        html,
        body {
            margin: 0px;
            height: 100%;
            width: 100%;
        }

        #map {
            width: 100%;
            height: 100%;
            background-color: #000;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script>

        var map = new maptalks.Map("map", {
            center: [120, 31],
            zoom: 11,
            pitch: 60,
            // bearing: 180,

            centerCross: true,
            doubleClickZoom: false,
            baseLayer: new maptalks.TileLayer('tile', {
                urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
                subdomains: ['a', 'b', 'c', 'd'],
                attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
            })
        });

        // the ThreeLayer to draw buildings
        var threeLayer = new maptalks.ThreeLayer('t', {
            forceRenderOnMoving: true,
            forceRenderOnRotating: true
            // animation: true
        });
        var state;
        threeLayer.prepareToDraw = function (gl, scene, camera) {

            var light = new THREE.DirectionalLight(0xffffff);
            light.position.set(0, -10, 10).normalize();
            scene.add(light);
            scene.add(new THREE.AmbientLight(0xffffff, 0.2));
            addBar();
        };
        const sceneConfig = {
            postProcess: {
                enable: true,
                antialias: { enable: true }
            }
        };
        const groupLayer = new maptalks.GroupGLLayer('group', [threeLayer], { sceneConfig });
        groupLayer.addTo(map);

        var material = new THREE.MeshLambertMaterial({ color: '#fff', transparent: true });

        function randomLnglats() {
            const center = {
                x: 120,
                y: 31
            }
            const lnglats = [];
            while (lnglats.length < 100) {
                const lng = center.x + Math.random() * 0.5, lat = center.y + Math.random() * .4;
                lnglats.push([lng, lat]);
            }
            return lnglats;
        }

        var bars = [];
        function addBar() {
            threeLayer.removeMesh(bars);
            threeLayer._baseObjects = [];
            bars.forEach(bar => {
                bar.getObject3d().geometry.dispose();
                for (const key in bar) {
                    bar[key] = null;
                }
                bar = null;
            });
            bars.length = 0;
            material.color.setStyle(randomColor());
            bars = randomLnglats().map(lnglat => {
                return new BarText(lnglat, {}, material, threeLayer);
            })
            threeLayer.addMesh(bars);

            setTimeout(() => {
                addBar();
            }, 100);
        }


        const OPTIONS = {
            altitude: 0,
            radius: 500
        };

        class BarText extends maptalks.BaseObject {
            constructor(coordinate, options, material, layer) {
                options = maptalks.Util.extend({}, OPTIONS, options, { layer, coordinate });
                super();
                //Initialize internal configuration
                // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L135
                this._initOptions(options);
                const { altitude, radius } = options;
                //generate geometry
                const r = layer.distanceToVector3(radius, radius).x;
                const h = 20;
                const geometry = new THREE.BoxBufferGeometry(r, r, h);
                geometry.translate(0, 0, h / 2);

                //Initialize internal object3d
                // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L140
                this._createMesh(geometry, material);

                //set object3d position
                const z = layer.altitudeToVector3(altitude, altitude).x;
                const position = layer.coordinateToVector3(coordinate, z);
                this.getObject3d().position.copy(position);
            }
        }




    </script>
</body>

</html>